package com.dyg.service.Impl;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.dyg.model.Item;
import com.dyg.model.Resource;
import com.dyg.model.User;
import com.dyg.dao.UserMapper;
import com.dyg.redis.RedisUtils;
import com.dyg.service.BaseService;
import com.dyg.service.ResourceService;
import com.dyg.service.UserService;
import com.dyg.service.UserroleService;
import com.dyg.util.LuceneUtil;
import com.dyg.util.Md5Util;
import com.dyg.vo.UserVo;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.DataType;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;
@Service
public class UserServiceImpl  extends BaseService  implements UserService{

	@Autowired
	private UserMapper userMapper;
	
	@Autowired
	private UserroleService userroleService;
		
	@Override
	public void insertUser(User user)	{
		this.userMapper.insertUser(user);
	}

	@Override
	public void deleteUserById(String userId)	{
		this.userMapper.deleteUserById(userId);
	}

	@Override
	public void updateUser(User user)	{
		this.userMapper.updateUser(user);
	}

	@Override
	public User findUserById(String userId)	{
		return this.userMapper.findUserById(userId);
	}

	@Override
	public List<UserVo> findUserList()	{
		 	String key = "userlist";
		 	List<UserVo> userVoList = new ArrayList<UserVo>();
		 	List<User> userList = new ArrayList<User>();
		 	
		 	
		 	Directory directory = null;
		 	DirectoryReader ireader = null;
	        try {
	        	// 索引存储到硬盘
	    		File file = new File("d:/lucene");
	        	directory = FSDirectory.open(file);
	        	
	        	
	        	
				int exists = super.exists(key);
				if(exists == 1){
					userList = (List<User>) super.get(key);
				}else{
					userList = userMapper.findUserList();
					super.set(key, userList);
				}

				List<UserVo> userVoList1 = userToUserVo(userList);
				
				//构建索引    ikAnalyzer,分词器
				LuceneUtil.buildIndexer(directory,userVoList1);

				//根据keyword搜索索引   ikAnalyzer,分词器
				
				
				String[] multiFields = {"username","nickname"};
				String keyword = "admin,admin";
				
				// 设定搜索目录
	            ireader = DirectoryReader.open(directory);
	            IndexSearcher isearcher = new IndexSearcher(ireader);
	            
	            // new IKAnalyzer()  使用 IK分词器    
	            //lucene 自带的 Analyzer analyzer检索能力太差
	            MultiFieldQueryParser parser = new MultiFieldQueryParser(
	                    Version.LUCENE_47,multiFields, new IKAnalyzer());
	            
				//userVoList = LuceneUtil.searchIndexer(multiFields,keyword);
				
				// 设定具体的搜索词
	            Query query = parser.parse(keyword);
	            
	            //排序
	            //默认排序
	            //Sort sort = null;
	            //通过doc的id进行排序
	            //Sort sort = Sort.INDEXORDER;
	            //通过评分进行排序
	            //Sort sort = Sort.RELEVANCE;
	            //正序
	            //Sort sort = new Sort(new SortField("id", SortField.Type.INT));
	            //倒序
	            Sort sort = new Sort(new SortField("id", SortField.Type.INT,true));
	            
	            ScoreDoc[] hits = isearcher.search(query, null, 10,sort).scoreDocs;
	            
	            for (int i = 0; i < hits.length; i++) {
	                Document hitDoc = isearcher.doc(hits[i].doc);
	                UserVo docToUserVo = docToUserVo(hitDoc);
	                
	                userVoList.add(docToUserVo);
	            }
	            
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		return userVoList;
	}

	
	/**
     * 登录逻辑
     * 1、先根据用户名查询用户对象
     * 2、如果有用户对象，则继续匹配密码
     * 如果没有用户对象，则抛出异常
     * @param username
     * @param password
     * @return
     */
	@Override
	public User login(String username, String password) {
		return  userMapper.loadByUserName(username);
	}

	/**
     * 批量添加用户角色关联表数据
     * @param user
     * @param rids
     */
	@Override
	public User add(User user, List<Integer> rids) {
		Integer userId = this.add(user).getId();
		
		//为单个用户设置多个角色
		userroleService.addUserRoles(userId,rids);
		
		return user;
	}

    /**
     * 返回新插入用户数据的主键
     * @param user
     * @return
     */
	@Override
	public User add(User user) {
		// 使用用户名作为盐值，MD5 算法加密
        user.setPassword(Md5Util.md5(user.getPassword(),user.getUsername()));
        userMapper.add(user);
        return user;
	}
	
	
	
	public List<UserVo> userToUserVo(List<User> userList){
		
		List<UserVo> userVoList = new ArrayList<UserVo>();
		
		if(userList != null && userList.size() > 0){
			for (User user : userList) {
				UserVo userVo = new UserVo();
				
				userVo.setId(user.getId()+"");
				userVo.setUsername(user.getUsername());
				userVo.setPassword(user.getPassword());
				userVo.setNickname(user.getNickname());
				userVo.setStatus(user.getStatus()+"");
				
				userVoList.add(userVo);
			}
		}
		
		
		return userVoList;
	}
	
	public UserVo docToUserVo(Document hitDoc){
		UserVo userVo = new UserVo();
		
		try {
			// 对多field进行搜索
			java.lang.reflect.Field[] fields = UserVo.class.getDeclaredFields();
			int length = fields.length;
			String[] multiFields = new String[length];
			for (int i = 0; i < length; i++) {
			    multiFields[i] = fields[i].getName();
			}
			
			for (String field : multiFields) {
			     String setMethodName = "set"+LuceneUtil.toFirstLetterUpperCase(field);
			     userVo.getClass().getMethod(setMethodName, String.class).invoke(userVo, hitDoc.get(field));
			     
			
			
			}
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return userVo;
	}
	

	
	
	
	
	
	

}
